﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;

public class ForcesDeploy : MonoBehaviour {

	private static ForcesDeploy instance;
	
	public static ForcesDeploy Instance{
		get{
			return instance;
		}
	}	
	
	void Awake()
	{
		instance = this;
		isActive=true;
	}

	public Transform playerPosParent;
	public Transform pc1Pos;
	List<ForcesDeploySpot> deploySpotList = new List<ForcesDeploySpot>();

	public float gapBetweenChar = 2;

	public int nextDeployIndex;
	public GameObject prefabDeploySpotFX;
	public GameObject prefabDeploySpot;
	public GameObject prefabSelectedMemberFX;
	GameObject selectedMemberFX;

	public int [] lineMax;
	int [] lineTotalMax;
	public int totalDeploySpotCount;
	public int maxDeployable;
	public static bool isDeploying;
	public static bool isActive;
	public static List<GameObject> deployedPawnList = new List<GameObject>();
	Dictionary<int, GameObject> pawnGoDic = new Dictionary<int, GameObject>();
	public Dictionary<int, bool> isDeployedDic = new Dictionary<int, bool>();

	public MemberModel selectedMember;

	void Start()
	{
		lineTotalMax = new int[3];
		lineMax = new int[3];
		lineMax[0] = 8;
		lineMax[1] = 7;
		lineMax[2] = 6;
		lineTotalMax[0] = lineMax[0];
		lineTotalMax[1] = lineMax[0] + lineMax[1];
		lineTotalMax[2] = lineMax[0] + lineMax[1] + lineMax[2];
		totalDeploySpotCount = lineTotalMax[2];
		maxDeployable = 20;

		/*
		SoundController.Create();
		ResourceManager.Inst.PatchDataFile( ()=> {
			GameData.Init();
			CashData.Init();
			//TextData.Init();
			EventData.Init();
		});*/

		Init();
		//NetworkManager.Instance.C2S_LOGIN(AuthPlatformID.None, "hoony8", string.Empty, ResponseLogin, null);
	}

//	private void ResponseLogin(ResponseModel<UserModel> result)
//	{
//		if (result.ecode != 0)
//			return;
//		
//		Debug.Log(result.data.account);
//		UserData.Instance.userModel = result.data;
//		Init();
//	}

	void Init()
	{
		CalcDeployPosition();
	}

	void CalcDeployPosition()
	{
		int nLine = 0;
		for(int i=0; i<totalDeploySpotCount; i++) {
			Vector3 newPcPos = pc1Pos.localPosition;

			if(i< lineTotalMax[0])
				nLine = 0;
			else if(i>=lineTotalMax[0] && i<lineTotalMax[1])
				nLine = 1;
			else
				nLine = 2;

			int nPos = i % lineMax[nLine];

			newPcPos.x -= (gapBetweenChar * nPos);	
			if(nLine==1)
				newPcPos.x -= gapBetweenChar/2.0f;
			else if(nLine==2)
				newPcPos.x -= gapBetweenChar;
			newPcPos.z -= (gapBetweenChar * nLine);
			GameObject spotGo = Instantiate( prefabDeploySpot) as GameObject;
			ForcesDeploySpot spot = spotGo.GetComponent<ForcesDeploySpot>();
			deploySpotList.Add(spot);
			spotGo.transform.parent = playerPosParent;
			spotGo.transform.localPosition = newPcPos;
			spotGo.transform.localRotation = Quaternion.identity;
			spot.index = i;
			spot.nLine = nLine;

			spot.spotFX = Instantiate(prefabDeploySpotFX) as GameObject;
			spot.spotFX.transform.parent = spotGo.transform;
			spot.spotFX.transform.localPosition = Vector3.zero;
			spot.spotFX.transform.localRotation = Quaternion.identity;
			spot.spotFX.SetActive(false);
		}
	}

	public void Deploy(int no, int modelID, int index)
	{
		if(index>= deploySpotList.Count) {
			Debug.Log("over max. cannot Deploy");
			return;
		}
		GameObject pawnGo = null;
		if(pawnGoDic.ContainsKey(no) )
			pawnGo = pawnGoDic[no];
		else {
			pawnGo = BattleResManager.CreatePawn(0, modelID, false);
			pawnGoDic.Add (no, pawnGo);
		}

		deploySpotList[index].Deploy(no, pawnGo);
		pawnGo.transform.parent = deploySpotList[index].transform;
		pawnGo.transform.localPosition = Vector3.zero;
		pawnGo.transform.localRotation = Quaternion.identity;
	}

	public void UnDeploySelectedMember()
	{
		ForcesDeploySpot spot = FindSelectedMemberDeployedSpot();
		if(spot!=null) {
			ForcesDeployScene scene = ForcesDeployScene.Instance as ForcesDeployScene;
			scene.SetDeployedCheck(spot.mNo, false);
			spot.UnDeploy();
		}
	}

	public void UnDeployAll()
	{
		foreach(ForcesDeploySpot spot in deploySpotList)
			spot.UnDeploy();
	}

	List<int> deployMemberNoList = new List<int>();
	public void SaveDeploy(int nSaveSlot)
	{
		deployMemberNoList.Clear ();
		for(int i=0; i<totalDeploySpotCount; i++) {
			if(!deploySpotList[i].isDeployed)
				deployMemberNoList.Add(0);
			else
				deployMemberNoList.Add(deploySpotList[i].mNo);
		}

		if(deployMemberNoList.Count>0) {
			try {
				//serialize
				using (Stream stream = File.Open(GetDeployInfoFile(nSaveSlot), FileMode.Create))
				{
					var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
					bformatter.Serialize(stream, deployMemberNoList);
				}
			}
			catch(Exception ex) {
			}
		}
		else
			Debug.Log("Save fail  empty slot "+nSaveSlot);
	}

	public void LoadDeploy(int nSaveSlot)
	{
		if(isDeploying) 
			return;
		deployMemberNoList.Clear();
		//deserialize
		try {
			using (Stream stream = File.Open(GetDeployInfoFile(nSaveSlot), FileMode.Open))
			{
				var bformatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
				deployMemberNoList = (List<int>)bformatter.Deserialize(stream);
			}

			isDeploying=true;
			StartCoroutine("CoLoadDeploy", nSaveSlot);
		}
		catch(Exception ex) {
			Debug.LogError(nSaveSlot+"  save file not found");
			UnDeployAll();
			ForcesDeployScene scene = ForcesDeployScene.Instance as ForcesDeployScene;
			scene.ClearDeployTagAll();
		}

	}

	IEnumerator CoLoadDeploy(int nSaveSlot)
	{
		ForcesDeployScene scene = ForcesDeployScene.Instance as ForcesDeployScene;
		scene.ClearDeployTagAll();
		if(deployMemberNoList.Count>0) 
		{
			UnDeployAll();

			for(int i=0; i<totalDeploySpotCount; i++) {
				if(deployMemberNoList[i]==0)
					continue;
				MemberModel memModel = scene.SetDeployedCheck(deployMemberNoList[i], true);
				if(memModel.model==0) {
					Debug.LogError(" not found model ID");
					continue;
				}
				scene.SetDeployTag(deployMemberNoList[i]);
				Deploy(deployMemberNoList[i], memModel.model, i);
				//UICharToDeploy uiChar = UIDeployPanel.Instance.FindUIChar(deployMemberNoList[i]);
				//uiChar.Deploy();
				yield return null;
			}

		}
		else
			Debug.Log("Load fail  empty slot "+nSaveSlot);
		scene.UpdateInfoUI();
		isDeploying=false;
	}

	string GetDeployInfoFile(int nSaveSlot)
	{
		Debug.Log( Application.persistentDataPath );
		return string.Format("{0}/deploy{1}.bin",Application.persistentDataPath, nSaveSlot);
	}

	public void ShowSelectedMemberFX(int no)
	{
		ForcesDeploySpot spot = FindDeployedSpot(no);
		if(spot!=null) 
			ShowSelectedMemberFX(no, spot.pawnGo, true);
		else
			ShowSelectedMemberFX(no, null, false);
	}

	public void ShowSelectedMemberFX(int no, GameObject pawnGo, bool bShow)
	{
		ForcesDeployScene scene = ForcesDeployScene.Instance as ForcesDeployScene;
		if(bShow) {
			if(selectedMemberFX==null)
				selectedMemberFX = Instantiate(prefabSelectedMemberFX) as GameObject;
			selectedMemberFX.SetActive(true);
			selectedMemberFX.transform.parent = pawnGo.transform;
			selectedMemberFX.transform.localPosition = Vector3.zero;
			selectedMemberFX.transform.localRotation = Quaternion.identity;
			scene.delButton.SetActive(true);
		}
		else {
			if(selectedMemberFX!=null)
				selectedMemberFX.SetActive(false);
			scene.delButton.SetActive(false);
		}
	}

	public void CheckDeployable(MemberModel memModel, bool isModifyMode)
	{
		selectedMember = memModel;
		ShowSelectedMemberFX(selectedMember.no);
		foreach(ForcesDeploySpot spot in deploySpotList) {
			if(!spot.isDeployed) {
				if(isModifyMode)
					spot.spotFX.SetActive(true);
			}
		}
	}

	public void TurnOffAllSpotFX()
	{
		foreach(ForcesDeploySpot spot in deploySpotList)
			spot.spotFX.SetActive(false);
	}

	public bool IsDeployed(int no)
	{
		if( isDeployedDic.ContainsKey(no) )
			return isDeployedDic[no];
		else
			return false;
	}

	public bool IsDeployedMax()
	{
		int nCount = 0;
		foreach(ForcesDeploySpot spot in deploySpotList) {
			if(spot.isDeployed)
				nCount++;
		}
		return (nCount>=maxDeployable);
	}

	public ForcesDeploySpot DeploySelectedMember(int index)
	{
		ForcesDeploySpot prevSpot = FindSelectedMemberDeployedSpot();
		if(prevSpot!=null)
			prevSpot.UnDeploy();
		ForcesDeployScene scene = ForcesDeployScene.Instance as ForcesDeployScene;
		scene.SetDeployedCheck(selectedMember.no, true);
		Deploy(selectedMember.no, selectedMember.model, index);
		return prevSpot;
	}

	ForcesDeploySpot FindDeployedSpot(int no)
	{
		foreach(ForcesDeploySpot spot in deploySpotList) {
			if(spot.mNo == no)
				return spot;
		}
		return null;
	}

	public ForcesDeploySpot FindSelectedMemberDeployedSpot()
	{
		return FindDeployedSpot(selectedMember.no);
	}
}
